package org.apache.flink.connector.httptm;

import lombok.Data;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 请求信息
 */
@Data
public class RequestInfo {
    private String url;
    private Map<String, String> format = new HashMap<>();
    private Map<String, String> queryParams = new HashMap<>();
    private Map<String, String> headers = new HashMap<>();
    private String body;

    public RequestInfo(String url) {
        this.url = url;
    }

    public RequestInfo(String url, Map<String, String> format) {
        if (format != null) {
            this.format.putAll(format);
        }
        this.setUrl(url);
    }

    /**
     * 设置 url参数
     * @param queryParams 参数
     */
    public void setQueryParams(Map<String, String> queryParams) {
        queryParams.forEach(this::setQueryParam);
    }


    /**
     * 设置 Headers
     * @param headers headers
     */
    public void setHeaders(Map<String, String> headers) {
        headers.forEach(this::setHeader);
    }

    /**
     * 设置 url参数
     * @param key key
     * @param value 值
     */
    public void setQueryParam(String key, String value) {
        this.queryParams.put(key, formatValue(value));
    }

    /**
     * 设置 Header
     * @param key key
     * @param value 值
     */
    public void setHeader(String key, String value) {
        this.headers.put(key, formatValue(value));
    }

    private String formatValue(String value) {
        if(!format.isEmpty() && value.contains("${")) {
            for (Map.Entry<String, String> entry : format.entrySet()) {
                value = value.replace("${" + entry.getKey() + "}", entry.getValue());
            }
        }
        return value;
    }

    /**
     * 设置 url
     * @param url url
     */
    public void setUrl(String url) {
        this.url = formatValue(url);
    }

    /**
     * 设置 body
     * @param body body
     */
    public void setBody(String body) {
        this.body = formatValue(body);
    }

    /**
     * 生成URI
     * @return URI
     */
    public URI getURI() {
        if (queryParams != null && !queryParams.isEmpty()) {
            url = url + (url.contains("?") ? "&" : "?") + this.encodeUrlForm(queryParams);
        }
        try {
            return new URI(url);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

    public byte[] getBodyBytes(Charset charset) {
        if (body == null) {
            return null;
        }
        return body.getBytes(charset);
    }

    /**
     * 获取 form字符串, URL编码
     * @param queryParams 参数
     * @return 编码后字符串
     */
    private String encodeUrlForm(Map<String, String> queryParams) {
        return queryParams.entrySet().stream().map(m -> {
            try {
                return URLEncoder.encode(m.getKey(), "UTF-8") + "=" + URLEncoder.encode(m.getValue(), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }).collect(Collectors.joining("&"));
    }
}
